From c545221c2596533fd3659c22c2c97290d97c1e65 Mon Sep 17 00:00:00 2001 From: Tomaka17 Date: Mon, 7 Jul 2014 18:33:45 +0200 Subject: [PATCH] Support for multiple and cleaner build commands --- src/cargo/core/manifest.rs | 12 ++-- src/cargo/ops/cargo_rustc.rs | 5 +- src/cargo/util/toml.rs | 14 +++- tests/test_cargo_compile.rs | 125 +++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 11 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index ffd1e6eee..88fd29e7a 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -19,7 +19,7 @@ pub struct Manifest { targets: Vec, target_dir: Path, sources: Vec, - build: Option, + build: Vec, unused_keys: Vec, } @@ -40,7 +40,7 @@ pub struct SerializedManifest { authors: Vec, targets: Vec, target_dir: String, - build: Option, + build: Option>, } impl> Encodable for Manifest { @@ -54,7 +54,7 @@ impl> Encodable for Manifest { authors: self.authors.clone(), targets: self.targets.clone(), target_dir: self.target_dir.display().to_str(), - build: self.build.clone(), + build: if self.build.len() == 0 { None } else { Some(self.build.clone()) }, }.encode(s) } } @@ -185,7 +185,7 @@ impl Show for Target { impl Manifest { pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path, sources: Vec, - build: Option) -> Manifest { + build: Vec) -> Manifest { Manifest { summary: summary.clone(), authors: Vec::new(), @@ -233,8 +233,8 @@ impl Manifest { self.sources.as_slice() } - pub fn get_build<'a>(&'a self) -> Option<&'a str> { - self.build.as_ref().map(|s| s.as_slice()) + pub fn get_build<'a>(&'a self) -> &'a [String] { + self.build.as_slice() } pub fn add_unused_key(&mut self, s: String) { diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs index 6c6218cf1..5832d8830 100644 --- a/src/cargo/ops/cargo_rustc.rs +++ b/src/cargo/ops/cargo_rustc.rs @@ -109,9 +109,8 @@ fn compile(targets: &[&Target], pkg: &Package, let mut cmds = Vec::new(); // TODO: Should this be on the target or the package? - match pkg.get_manifest().get_build() { - Some(cmd) => cmds.push(compile_custom(pkg, cmd, cx)), - None => {} + for build_cmd in pkg.get_manifest().get_build().iter() { + cmds.push(compile_custom(pkg, build_cmd.as_slice(), cx)); } // After the custom command has run, execute rustc for all targets of our diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 15a4e11d5..f04821eb3 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -119,7 +119,13 @@ pub struct TomlProject { // FIXME #54: should be a Version to be able to be Decodable'd directly. pub version: String, pub authors: Vec, - build: Option, + build: Option, +} + +#[deriving(Encodable,Decodable,PartialEq,Clone,Show)] +pub enum TomlBuildCommandsList { + SingleBuildCommand(String), + MultipleBuildCommands(Vec) } impl TomlProject { @@ -178,7 +184,11 @@ impl TomlManifest { targets.as_slice(), &Path::new("target"), sources, - project.build.clone()), + match project.build { + Some(SingleBuildCommand(ref cmd)) => vec!(cmd.clone()), + Some(MultipleBuildCommands(ref cmd)) => cmd.clone(), + None => Vec::new() + }), nested_paths)) } } diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 9fa6a8aa8..6ba32c5bc 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -369,6 +369,70 @@ test!(custom_build { .with_stderr("")); }) +test!(custom_multiple_build { + let mut build1 = project("builder1"); + build1 = build1 + .file("Cargo.toml", r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [[bin]] name = "foo" + "#) + .file("src/foo.rs", r#" + fn main() { + let args = ::std::os::args(); + assert_eq!(args.get(1), &"hello".to_string()); + assert_eq!(args.get(2), &"world".to_string()); + } + "#); + assert_that(build1.cargo_process("cargo-build"), + execs().with_status(0)); + + let mut build2 = project("builder2"); + build2 = build2 + .file("Cargo.toml", r#" + [project] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [[bin]] name = "bar" + "#) + .file("src/bar.rs", r#" + fn main() { + let args = ::std::os::args(); + assert_eq!(args.get(1), &"cargo".to_string()); + } + "#); + assert_that(build2.cargo_process("cargo-build"), + execs().with_status(0)); + + let mut p = project("foo"); + p = p + .file("Cargo.toml", format!(r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + build = [ "{} hello world", "{} cargo" ] + + [[bin]] name = "foo" + "#, escape_path(&build1.bin("foo")), escape_path(&build2.bin("bar")))) + .file("src/foo.rs", r#" + fn main() {} + "#); + assert_that(p.cargo_process("cargo-build"), + execs().with_status(0) + .with_stdout(format!(" Compiling foo v0.5.0 (file:{})\n", + p.root().display())) + .with_stderr("")); +}) + test!(custom_build_failure { let mut build = project("builder"); build = build @@ -413,6 +477,67 @@ task '
' failed at 'nope', {filename}:2\n\ ", build.bin("foo").display(), filename = format!("src{}foo.rs", path::SEP)))); }) +test!(custom_second_build_failure { + let mut build1 = project("builder1"); + build1 = build1 + .file("Cargo.toml", r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [[bin]] name = "foo" + "#) + .file("src/foo.rs", r#" + fn main() { println!("Hello!"); } + "#); + assert_that(build1.cargo_process("cargo-build"), + execs().with_status(0)); + + let mut build2 = project("builder2"); + build2 = build2 + .file("Cargo.toml", r#" + [project] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [[bin]] + name = "bar" + "#) + .file("src/bar.rs", r#" + fn main() { fail!("nope") } + "#); + assert_that(build2.cargo_process("cargo-build"), execs().with_status(0)); + + + let mut p = project("foo"); + p = p + .file("Cargo.toml", format!(r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + build = [ "{}", "{}" ] + + [[bin]] + name = "foo" + "#, escape_path(&build1.bin("foo")), escape_path(&build2.bin("bar")))) + .file("src/foo.rs", r#" + fn main() {} + "#); + assert_that(p.cargo_process("cargo-build"), + execs().with_status(101).with_stderr(format!("\ +Could not execute process `{}` (status=101)\n\ +--- stderr\n\ +task '
' failed at 'nope', {filename}:2\n\ +\n\ +", build2.bin("bar").display(), filename = format!("src{}bar.rs", path::SEP)))); +}) + test!(custom_build_env_vars { let mut p = project("foo"); let mut build = project("builder"); -- 2.30.2